package j.framework.qmd.controller;

import j.framework.core.Action;
import j.framework.core.FApplication;
import j.framework.core.ServiceException;
import j.framework.core.WebRequestConfiguration;
import j.framework.qmd.core.*;
import j.framework.qmd.jdbc.QueryMetadataService;
import j.framework.qmd.jdbc.QueryMetadataServiceImpl;
import j.data.ActionResult;
import j.data.PagedData;
import j.util.DateUtils;
import j.util.New;
import j.util.StringUtils;
import j.util.json.JsonUtils;
import j.util.web.BaseController;
import j.util.web.ExceptionType;
import j.util.web.HttpView;
import j.util.web.WebRequest;
import org.apache.poi.hssf.usermodel.*;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * User: jason
 * Date: 14-7-18 上午10:11
 */
@WebServlet(urlPatterns = "/user/sys/qmdManager")
public class QueryMetadataController extends BaseController {

    private QueryMetadataService service = new QueryMetadataServiceImpl();

    @Override
    public void doDefaultGet(HttpView view) throws ServletException, IOException {
        view.forward("qmd/qmdManager");
    }

    @WebRequest(action = "getList")
    public void doGetList(HttpView view) throws ServletException, IOException {
        PagedData<List<QueryMetadata>> pd = service.getQueryList(view.getUser(),
                view.getDesId("functionId"), view.getIntParamter("page"), view.getIntParamter("rows"));
        view.toEasyUiGrid(pd.getTotal(), pd.getDataItems());
    }

    @WebRequest(action = "edit")
    public void doShowAddEditQueryMetadataUI(HttpView view) throws ServletException, IOException {
        String queryId = view.getParameter("queryId");
        if(StringUtils.isNotEmpty(queryId)){
            QueryMetadata qmd = service.getQueryMetadata(queryId);
            if(qmd != null){
                view.setAttribute("d",qmd);
            }
        }else{
            QueryMetadata qmd = new QueryMetadata();
            qmd.setFunctionId(view.getDesId("functionId"));
            if(StringUtils.isNotEmpty(qmd.getFunctionId())){
                view.setAttribute("d",qmd);
            }
        }
        view.forward("qmd/editQuery");
    }

    @WebRequest(action="save",exceptionType = ExceptionType.TARGET_IFRAME)
    public void doSaveQueryMetadata(HttpView view) throws ServletException, IOException {
        ActionResult ar = ActionResult.New();
        QueryMetadata qmd = view.getBean(QueryMetadata.class,ar);
        if(StringUtils.isNotEmpty(qmd.getFunctionId())){
            qmd.setFunctionId(view.getDesId("functionId"));
        }
        service.saveQueryMetadata(view.getUser(),qmd,ar);
        view.toResult(ar);
    }
    @WebRequest(action = "delq",exceptionType = ExceptionType.AJAX)
    public void doDeleteQuery(HttpView view) throws ServletException, IOException {
        ActionResult ar = ActionResult.New();
        service.deleteQueryMetadata(view.getUser(), view.getParameter("queryId"), ar);
        view.toClient(ar);
    }
    @WebRequest(action = "refresh",exceptionType = ExceptionType.AJAX)
    public void doRefresh(HttpView view) throws ServletException, IOException {
        QueryManager.getInstance().refreshQueryMetadata(view.getParameter("queryId"));
        view.toClient(ActionResult.New());
    }

    @WebRequest(action = "review")
    public void doShowReviewQueryUI(HttpView view) throws ServletException, IOException {
        /*String queryId = view.getParameter("queryId");
        if(StringUtils.isNotEmpty(queryId)){
            view.setAttribute("qmd", QueryManager.getQueryMetadata(queryId));
        }*/
        view.forward("qmd/review");
    }

    @WebRequest(action = "q")
    public void doQuery(HttpView view) throws ServletException, IOException {
        String queryId = view.getParameter("queryId");
        QueryResult qr = QueryManager.queryForList(view.getUser(),QueryManager.getQueryMetadata(queryId), view.getMap());
        view.toEasyUiGrid(qr.getTotalRecords(),qr.getList(),qr.getFooter());
    }
    @WebRequest(action = "fe")
    public void doShowEditQueryFieldMetadataUI(HttpView view) throws ServletException, IOException {
        QueryMetadata qmd = service.getQueryMetadata(view.getParameter("queryId"));
        if(qmd != null){
            view.setAttribute("isTree",qmd.isShowByTree());
            List<QueryFieldMetadata> list = service.getQueryFieldMetadataList(qmd.getQueryId());
            view.setAttribute("list",list);
        }
        view.forward("qmd/editQueryFieldMetadata");
    }
    /**
     * 批量保存查询字符定义
     * @param view
     * @throws javax.servlet.ServletException
     * @throws java.io.IOException
     */
    @WebRequest(action = "savefm", exceptionType = ExceptionType.TARGET_IFRAME)
    public void doSaveQueryFieldMetadata(HttpView view) throws ServletException, IOException {
        ActionResult ar = ActionResult.New();
        boolean isTree = view.getBooleanParameter("isTree");
        String queryId = view.getParameter("queryId");
        if(StringUtils.isNotEmpty(queryId)){
            List<QueryFieldMetadata> list = service.getQueryFieldMetadataList(queryId);
            DataType dt;
            String str;
            DataAlign dataAlign;
            for(QueryFieldMetadata md : list){
                md.setTableAliasName(view.getParameter(md.getFieldId()+"_tableAliasName"));
                md.setDisplayName(view.getParameter(md.getFieldId()+"_displayName"));
                md.setDisplayNameTag(view.getParameter(md.getFieldId() + "_displayNameTag"));
                md.setWidth(view.getIntParamter(md.getFieldId() + "_width"));
                str =view.getParameter(md.getFieldId() + "_dataType");
                if(StringUtils.isNullOrEmpty(str)){
                    dt = DataType.STRING;
                }else{
                    dt = DataType.valueOf(str);
                }
                md.setDataType(dt);
                md.setPrimaryKey(view.getBooleanParameter(md.getFieldId() + "_primaryKey"));
                md.setUsedFieldNameAsKey(view.getBooleanParameter(md.getFieldId() + "_usedFieldNameAsKey"));
                md.setSuppressible(view.getBooleanParameter(md.getFieldId() + "_suppressible"));
                md.setSortSupported(view.getBooleanParameter(md.getFieldId() + "_sortSupported"));
                md.setDefaultSort(view.getBooleanParameter(md.getFieldId() + "_defaultSort"));
                if(md.isDefaultSort()){
                    md.setDefaultSortOrder(view.getParameter(md.getFieldId() + "_defaultSortOrder"));
                }
                md.setDisplayOrder(view.getIntParamter(md.getFieldId() + "_displayOrder"));
                str = view.getParameter(md.getFieldId() + "_columnHeaderAlign");
                if(StringUtils.isNullOrEmpty(str)){
                    dataAlign = DataAlign.CENTER;
                }else{
                    dataAlign = DataAlign.valueOf(str);
                }
                md.setColumnHeaderAlign(dataAlign);
                str = view.getParameter(md.getFieldId() + "_columnDataAlign");
                if(StringUtils.isNullOrEmpty(str)){
                    dataAlign = DataAlign.CENTER;
                }else{
                    dataAlign = DataAlign.valueOf(str);
                }
                md.setColumnDataAlign(dataAlign);
                md.setClientFormatter(view.getParameter(md.getFieldId()+"_clientFormatter"));
                md.setFormatterMethodName(view.getParameter(md.getFieldId()+"_formatterMethodName"));
                if(isTree){
                    md.setAsTreeField(view.getBooleanParameter(md.getFieldId() + "_asTreeField"));
                }
                str = view.getParameter(md.getFieldId()+"_formatType");
                if(StringUtils.isNullOrEmpty(str)){
                    md.setFormatType(FormatType.NONE);
                }else{
                    md.setFormatType(FormatType.valueOf(str));
                    md.setFormatOptions(view.getParameter(md.getFieldId()+"_formatOptions"));
                }
                if(md.getFormatType().equals(FormatType.DICTIONARY)){
                    md.setDictionaryId(view.getParameter(md.getFieldId()+"_dictionaryId"));
                }
            }

            String treeParentFieldId = null;
            String treeFieldId = null;
            if(isTree){
                treeFieldId = view.getParameter("treeFieldId");
                if(StringUtils.isNullOrEmpty(treeFieldId)){
                    ar.add("此查询被定义为树形结构，必须指定一列做为树级字段！");
                }
                treeParentFieldId = view.getParameter("treeParentFieldId");
                if(StringUtils.isNullOrEmpty(treeParentFieldId)){
                    ar.add("此查询被定义为树形数据，必须指定一列做为父级数据！");
                }
            }
            if(ar.isOk()){
                service.doSaveQueryFieldMetadata(view.getUser(),queryId,treeFieldId,treeParentFieldId,list,ar);
            }
        }else{
            ar.add("没有指定查询");
        }
        view.toClient1(ar, "parent.doOk();");
    }

    @WebRequest(action = "frequests")
    public void doGetFunctionRequests(HttpView view) throws ServletException, IOException {
        List<WebRequestConfiguration> list = service.getWebRequests(view.getDesId("functionId"));
        view.toEasyUiGrid(list.size(), list);
    }
    @WebRequest(action = "editr")
    public void doShowEditRequestUI(HttpView view) throws ServletException, IOException {
        String requestId = view.getDesId("requestId");
        if(StringUtils.isNotEmpty(requestId)){
            WebRequestConfiguration d = FApplication.getInstance().getWebRequestConfiguration(requestId);
            if(d != null){
                view.setAttribute("d", d);
            }
        }else{
            WebRequestConfiguration d = new WebRequestConfiguration();
            d.setFunctionId(view.getDesId("functionId"));
            view.setAttribute("d",d);
        }
        view.forward("qmd/editRequest");
    }

    @WebRequest(action="saver",exceptionType = ExceptionType.TARGET_IFRAME)
    public void doSaveWebRequest(HttpView view) throws ServletException, IOException {
        ActionResult ar = ActionResult.New();
        WebRequestConfiguration wrc = view.getBean(WebRequestConfiguration.class,ar);
        if(StringUtils.isNotEmpty(wrc.getRequestId())){
            wrc.setRequestId(view.getDesId("requestId"));
        }
        service.saveWebRequestConfiguration(view.getUser(),wrc,ar);
        view.toResult(ar);
    }
    @WebRequest(action = "delr",exceptionType = ExceptionType.AJAX)
    public void doDeleteWebRequest(HttpView view) throws ServletException, IOException {
        ActionResult ar = ActionResult.New();
        service.deleteWebRequestConfiguration(view.getUser(), view.getDesId("requestId"), ar);
        view.toClient(ar);
    }
    @WebRequest(action = "getfactions",exceptionType = ExceptionType.AJAX)
    public void doGetFunctionActions(HttpView view) throws ServletException, IOException {
        List<Action> list = FApplication.getInstance().getFunctionActions(view.getDesId("fid"));
        view.toOut(JsonUtils.toJson(list));
    }
    @WebRequest(action = "excel",exceptionType = ExceptionType.AJAX)
    public void toExcel(HttpView view) throws ServletException, IOException {
        String queryId = view.getParameter("queryId");
        QueryMetadata qmd = QueryManager.getQueryMetadata(queryId);
        QueryResult qr = QueryManager.queryForList(view.getUser(),qmd, view.getMap());
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 生成一个表格
        HSSFSheet sheet = workbook.createSheet(qmd.getName());

        HSSFCellStyle dateStyle = workbook.createCellStyle();
        dateStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        dateStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        HSSFDataFormat format = workbook.createDataFormat();
        dateStyle.setDataFormat(format.getFormat("yyyy-MM-dd HH:mm:ss"));
        //产生表格标题行
        HSSFRow row = sheet.createRow(0);
        HSSFCell cell;
        int index = 0;
        HSSFRichTextString text;
        Map<Integer,QueryFieldMetadata> indexKeyMapper = New.map();
        for(QueryFieldMetadata qfmd : qmd.getFieldMetadataList()){
            if(qfmd.isSuppressible()){
                //这是隐藏列，不导出
                continue;
            }
            indexKeyMapper.put(index,qfmd);
            cell = row.createCell(index++);
            text = new HSSFRichTextString(qfmd.getDisplayName());
            cell.setCellValue(text);
        }
        int rowIndex = 1;
        QueryFieldMetadata qfmd;
        Object v;
        boolean b;
        for(Map<String,Object> map : qr.getList()){
            row = sheet.createRow(rowIndex++);
            index = 0;
            for(int i=0;i<indexKeyMapper.size();i++){
                cell = row.createCell(index++);
                qfmd = indexKeyMapper.get(i);
                v = map.get(qfmd.getFieldId());
                if(v == null){
                    continue;
                }
                if(qfmd.isSuppressible()){
                    //这是隐藏列，不导出
                    continue;
                }
                if(v instanceof String){
                    cell.setCellValue(String.valueOf(v));
                }
                else if(v instanceof Date){
                    cell.setCellStyle(dateStyle);
                    cell.setCellValue((Date)v);
                }else if(v instanceof Boolean){
                    b = (Boolean)v;
                    cell.setCellValue(b);
                }
                else if(v instanceof Integer || v instanceof Short || v instanceof Long || v instanceof Double || v instanceof Float){
                    cell.setCellValue(Double.valueOf(String.valueOf(v)));
                }else{
                    cell.setCellValue(String.valueOf(v));
                }
            }
        }
        //导出footer
        if(qr.getFooter()!=null && qr.getFooter().size()>0){
            for(Map<String,Object> map : qr.getFooter()){
                row = sheet.createRow(rowIndex++);
                index = 0;
                for(int i=0;i<indexKeyMapper.size();i++){
                    cell = row.createCell(index++);
                    qfmd = indexKeyMapper.get(i);
                    v = map.get(qfmd.getFieldId());
                    if(v == null){
                        continue;
                    }
                    if(v instanceof String){
                        cell.setCellValue(String.valueOf(v));
                    }
                    else if(v instanceof Date){
                        cell.setCellStyle(dateStyle);
                        cell.setCellValue((Date)v);
                    }else if(v instanceof Boolean){
                        b = (Boolean)v;
                        cell.setCellValue(b);
                    }
                    else if(v instanceof Integer || v instanceof Short || v instanceof Long || v instanceof Double || v instanceof Float){
                        cell.setCellValue(Double.valueOf(String.valueOf(v)));
                    }else{
                        cell.setCellValue(String.valueOf(v));
                    }
                }
            }
        }
        HttpServletResponse response = view.getResponse();
        response.setContentType("octets/stream");
        String fileName = qmd.getQueryId()+"_"+DateUtils.format(new Date(),"yyyy-MM-dd")+".xls";
        response.addHeader("Content-Disposition", "attachment;filename="+fileName);
        OutputStream out = response.getOutputStream();
        workbook.write(out);
        out.close();
    }
}
